//mini_project
//The calculator
//Author: Ziyao Zhou
//Time: 2021/11/23 ~ 2021/**/**
//First step: pins setting
#include <stdio.h> 
//#include "uart.h" 
//#include "TExaS.h" 
#define GPIO_PORTA_DATA_R       (*((volatile unsigned long *)0x400043FC))
#define GPIO_PORTA_DIR_R        (*((volatile unsigned long *)0x40004400))
#define GPIO_PORTA_AFSEL_R      (*((volatile unsigned long *)0x40004420))
#define GPIO_PORTA_PUR_R        (*((volatile unsigned long *)0x40004510))
#define GPIO_PORTA_DEN_R        (*((volatile unsigned long *)0x4000451C))
#define GPIO_PORTA_CR_R         (*((volatile unsigned long *)0x40004524))
#define GPIO_PORTA_AMSEL_R      (*((volatile unsigned long *)0x40004528))
#define GPIO_PORTA_PCTL_R       (*((volatile unsigned long *)0x4000452C))
#define PA2                     (*((volatile unsigned long *)0x40004010)) //LCD: E
#define PA3                     (*((volatile unsigned long *)0x40004020)) //LCD: RS
#define PA4                     (*((volatile unsigned long *)0x40004040)) //LCD: RW
#define PA5                     (*((volatile unsigned long *)0x40004080)) //LCD: BA
#define PA6                     (*((volatile unsigned long *)0x40004100)) //LCD: BK

#define GPIO_PORTB_DATA_R       (*((volatile unsigned long *)0x400053FC))
#define GPIO_PORTB_DIR_R        (*((volatile unsigned long *)0x40005400))
#define GPIO_PORTB_AFSEL_R      (*((volatile unsigned long *)0x40005420))
#define GPIO_PORTB_PUR_R        (*((volatile unsigned long *)0x40005510))
#define GPIO_PORTB_DEN_R        (*((volatile unsigned long *)0x4000551C))
#define GPIO_PORTB_CR_R         (*((volatile unsigned long *)0x40005524))
#define GPIO_PORTB_AMSEL_R      (*((volatile unsigned long *)0x40005528))
#define GPIO_PORTB_PCTL_R       (*((volatile unsigned long *)0x4000552C))
#define PB0                     (*((volatile unsigned long *)0x40005004)) //LCD D0
#define PB1                     (*((volatile unsigned long *)0x40005008)) //LCD D1
#define PB2                     (*((volatile unsigned long *)0x40005010)) //LCD D2
#define PB3                     (*((volatile unsigned long *)0x40005020)) //LCD D3
#define PB4                     (*((volatile unsigned long *)0x40005040)) //LCD D4
#define PB5                     (*((volatile unsigned long *)0x40005080)) //LCD D5
#define PB6                     (*((volatile unsigned long *)0x40005100)) //LCD D6
#define PB7                     (*((volatile unsigned long *)0x40005200)) //LCD D7
	
#define GPIO_PORTD_DATA_R       (*((volatile unsigned long *)0x400073FC))
#define GPIO_PORTD_DIR_R        (*((volatile unsigned long *)0x40007400))
#define GPIO_PORTD_AFSEL_R      (*((volatile unsigned long *)0x40007420))
#define GPIO_PORTD_PUR_R        (*((volatile unsigned long *)0x40007510))
#define GPIO_PORTD_DEN_R        (*((volatile unsigned long *)0x4000751C))
#define GPIO_PORTD_CR_R         (*((volatile unsigned long *)0x40007524))
#define GPIO_PORTD_AMSEL_R      (*((volatile unsigned long *)0x40007528))
#define GPIO_PORTD_PCTL_R       (*((volatile unsigned long *)0x4000752C))
#define GPIO_PORTD_LOCK_R       (*((volatile unsigned long *)0x40007520))
#define PD0                     (*((volatile unsigned long *)0x40007004)) //Keyboard ROW 1
#define PD1                     (*((volatile unsigned long *)0x40007008)) //Keyboard ROW 2
#define PD2                     (*((volatile unsigned long *)0x40007010)) //Keyboard ROW 3
#define PD3                     (*((volatile unsigned long *)0x40007020)) //Keyboard ROW 4
	
#define GPIO_PORTE_DATA_R       (*((volatile unsigned long *)0x400243FC))
#define GPIO_PORTE_DIR_R        (*((volatile unsigned long *)0x40024400))
#define GPIO_PORTE_AFSEL_R      (*((volatile unsigned long *)0x40024420))
#define GPIO_PORTE_PUR_R        (*((volatile unsigned long *)0x40024510))
#define GPIO_PORTE_DEN_R        (*((volatile unsigned long *)0x4002451C))
#define GPIO_PORTE_CR_R         (*((volatile unsigned long *)0x40024524))
#define GPIO_PORTE_AMSEL_R      (*((volatile unsigned long *)0x40024528))
#define GPIO_PORTE_PCTL_R       (*((volatile unsigned long *)0x4002452C))
#define PE0                     (*((volatile unsigned long *)0x40024004)) //Keyboard COL 1
#define PE1                     (*((volatile unsigned long *)0x40024008)) //Keyboard COL 2
#define PE2                     (*((volatile unsigned long *)0x40024010)) //Keyboard COL 3
#define PE3                     (*((volatile unsigned long *)0x40024020)) //Keyboard COL 4
	
#define GPIO_PORTF_DATA_R       (*((volatile unsigned long *)0x400253FC))
#define GPIO_PORTF_DIR_R        (*((volatile unsigned long *)0x40025400))
#define GPIO_PORTF_AFSEL_R      (*((volatile unsigned long *)0x40025420))
#define GPIO_PORTF_PUR_R        (*((volatile unsigned long *)0x40025510))
#define GPIO_PORTF_DEN_R        (*((volatile unsigned long *)0x4002551C))
#define GPIO_PORTF_LOCK_R       (*((volatile unsigned long *)0x40025520))
#define GPIO_PORTF_CR_R         (*((volatile unsigned long *)0x40025524))
#define GPIO_PORTF_AMSEL_R      (*((volatile unsigned long *)0x40025528))
#define GPIO_PORTF_PCTL_R       (*((volatile unsigned long *)0x4002552C))
#define PF0                     (*((volatile unsigned long *)0x40025004)) //LED
#define PF1                     (*((volatile unsigned long *)0x40025008)) // *
#define PF2                     (*((volatile unsigned long *)0x40025010)) // *
#define PF3                     (*((volatile unsigned long *)0x40025020)) //LED
#define SYSCTL_RCGC2_R          (*((volatile unsigned long *)0x400FE108))
#define SYSCTL_RIS_R            (*((volatile unsigned long *)0x400FE050))	
#define SYSCTL_RCC_R            (*((volatile unsigned long *)0x400FE060))
#define SYSCTL_RCC2_R           (*((volatile unsigned long *)0x400FE070))	
#define NVIC_ST_CTRL_R          (*((volatile unsigned long *)0xE000E010))
#define NVIC_ST_RELOAD_R        (*((volatile unsigned long *)0xE000E014))
#define NVIC_ST_CURRENT_R       (*((volatile unsigned long *)0xE000E018))
// Second step: function
void PortA_Init(void);
void PortB_Init(void);
void PortD_Init(void);
void PortE_Init(void);
void PortF_Init(void);
void delay(unsigned long time);
void keyboard_Init(void);
void keyboard(void);
void SysTick_Init(void);
void PLL_Init(void);
void LCD_Init(void);
void SysTick_Wait(unsigned long delay);
void lcdE_Pulse(void);
void lcd_zzy_writecommand(unsigned char c);
void lcd_zzy_data(char c);
void lcd_go(unsigned char row, unsigned char column);
void keypad_Init(void);
unsigned char read_zzy_pad(void);








//define the function
void PortA_Init(void){ 
	volatile unsigned long delay;
  //SYSCTL_RCGC2_R |= 0x00000020;     // 1) F clock
  delay = SYSCTL_RCGC2_R;           // delay   
  //GPIO_PORTF_LOCK_R = 0x4C4F434B;   // 2) unlock PortF PF0  
  GPIO_PORTA_CR_R |= 0x7C;           // allow changes to PA2,3,4,5,6       
  GPIO_PORTA_AMSEL_R &= 0x00;        // 3) disable analog function
  GPIO_PORTA_PCTL_R &= 0x00000000;   // 4) GPIO clear bit PCTL  
  GPIO_PORTA_DIR_R &= ~0x00;          // 5.1) no input, 
  GPIO_PORTA_DIR_R |= 0x7C;          // 5.2) PA2~6 output  
  GPIO_PORTA_AFSEL_R &= 0x00;        // 6) no alternate function
  GPIO_PORTA_PUR_R |= 0x00;          // enable pullup resistors on PF4,PF0       
  GPIO_PORTA_DEN_R |= 0x7C;          // 7) enable digital pins PF4-PF0     
}

void PortB_Init(void){ 
	volatile unsigned long delay;
  //SYSCTL_RCGC2_R |= 0x00000020;     // 1) F clock
  delay = SYSCTL_RCGC2_R;           // delay   
  //GPIO_PORTF_LOCK_R = 0x4C4F434B;   // 2) unlock PortF PF0  
  GPIO_PORTB_CR_R |= 0xFF;           // allow changes to PB0~7       
  GPIO_PORTB_AMSEL_R &= 0x00;        // 3) disable analog function
  GPIO_PORTB_PCTL_R &= 0x00000000;   // 4) GPIO clear bit PCTL  
  GPIO_PORTB_DIR_R &= ~0x00;          // 5.1) no input, 
  GPIO_PORTB_DIR_R |= 0xFF;          // 5.2) PB0~7 output  
  GPIO_PORTB_AFSEL_R &= 0x00;        // 6) no alternate function
  GPIO_PORTB_PUR_R |= 0x00;          // enable pullup resistors on PF4,PF0       
  GPIO_PORTB_DEN_R |= 0xFF;          // 7) enable digital pins PB0~7    
}

void PortD_Init(void){ 
	volatile unsigned long delay;
  //SYSCTL_RCGC2_R |= 0x00000008;     // 1) D clock
  delay = SYSCTL_RCGC2_R;           // delay   
  //GPIO_PORTD_LOCK_R = 0x4C4F434B;   // 2) unlock PortF PF0  
  GPIO_PORTD_CR_R |= 0x0F;           // allow changes to PD0~3      
  GPIO_PORTD_AMSEL_R &= 0x00;        // 3) disable analog function
  GPIO_PORTD_PCTL_R &= 0x00000000;   // 4) GPIO clear bit PCTL  
  GPIO_PORTD_DIR_R &= ~0x00;          // 5.1) no input, 
  GPIO_PORTD_DIR_R |= 0x0F;          // 5.2) PD0~3 output  
  GPIO_PORTD_AFSEL_R &= 0x00;        // 6) no alternate function
  GPIO_PORTD_PUR_R |= 0x0F;          // enable pullup resistors on PF4,PF0       
  GPIO_PORTD_DEN_R |= 0x0F;          // 7) enable digital pins PF4-PF0     
}

void PortE_Init(void){ 
	volatile unsigned long delay;
  //SYSCTL_RCGC2_R |= 0x00000020;     // 1) F clock
  delay = SYSCTL_RCGC2_R;           // delay   
  //GPIO_PORTF_LOCK_R = 0x4C4F434B;   // 2) unlock PortF PF0  
  GPIO_PORTE_CR_R |= 0x0F;           // allow changes to PE0~3      
  GPIO_PORTE_AMSEL_R &= 0x00;        // 3) disable analog function
  GPIO_PORTE_PCTL_R &= 0x00000000;   // 4) GPIO clear bit PCTL  
  GPIO_PORTE_DIR_R &= ~0x0F;          // 5.1) PE0~3 input, 
  GPIO_PORTE_DIR_R |= 0x00;          // 5.2) no output  
  GPIO_PORTE_AFSEL_R &= 0x00;        // 6) no alternate function
  GPIO_PORTE_PUR_R |= 0x00;          // enable pullup resistors on PF4,PF0       
  GPIO_PORTE_DEN_R |= 0x0F;          // 7) enable digital pins PF4-PF0     
}


void PortF_Init(void){ 
	volatile unsigned long delay;
  SYSCTL_RCGC2_R |= 0x00000020;     // 1) F clock
  delay = SYSCTL_RCGC2_R;           // delay   
  GPIO_PORTF_LOCK_R = 0x4C4F434B;   // 2) unlock PortF PF0  
  GPIO_PORTF_CR_R |= 0x1F;           // allow changes to PF4-0       
  GPIO_PORTF_AMSEL_R &= 0x00;        // 3) disable analog function
  GPIO_PORTF_PCTL_R &= 0x00000000;   // 4) GPIO clear bit PCTL  
  GPIO_PORTF_DIR_R &= ~0x11;          // 5.1) PF4,PF0 input, 
  GPIO_PORTF_DIR_R |= 0x08;          // 5.2) PF3 output  
  GPIO_PORTF_AFSEL_R &= 0x00;        // 6) no alternate function
  GPIO_PORTF_PUR_R |= 0x11;          // enable pullup resistors on PF4,PF0       
  GPIO_PORTF_DEN_R |= 0x1F;          // 7) enable digital pins PF4-PF0     
}

void SysTick_Init(void){
  NVIC_ST_CTRL_R = 0;                   // disable SysTick during setup
  NVIC_ST_RELOAD_R = 0x00FFFFFF;        // maximum reload value
  NVIC_ST_CURRENT_R = 0;                // any write to current clears it             
  NVIC_ST_CTRL_R = 0x00000005;          // enable SysTick with core clock
}

void PLL_Init(void){
  SYSCTL_RCC2_R |=  0x80000000; 
  SYSCTL_RCC2_R |=  0x00000800;
  SYSCTL_RCC_R = (SYSCTL_RCC_R &~0x000007C0)   
                 + 0x00000540;   
  SYSCTL_RCC2_R &= ~0x00000070;  
  SYSCTL_RCC2_R &= ~0x00002000;
  SYSCTL_RCC2_R |= 0x40000000;   
  SYSCTL_RCC2_R = (SYSCTL_RCC2_R&~ 0x1FC00000)  
                  + (4<<22);      
  while((SYSCTL_RIS_R&0x00000040)==0){
	SYSCTL_RCC2_R &= ~0x00000800;
	};  
  
}
/*
//-----------------------------------function of LCD--------------------------------------------------------------------------
void LCD_Init(void) { //not finish
PortA_Init();
PortB_Init();
delay(20);
GPIO_PORTA_DATA_R = 0x00;
GPIO_PORTB_DATA_R = 0x00;
delay(20);
GPIO_PORTA_DATA_R = 0x00;
GPIO_PORTB_DATA_R = 0x0C;
lcdE_Pulse();
delay(4);
GPIO_PORTA_DATA_R = 0x00;
GPIO_PORTB_DATA_R = 0x0C;
lcdE_Pulse();
for(i=0; i<150; i++)    {
       SysTick_Wait(80);                
    }
GPIO_PORTA_DATA_R = 0x00;
GPIO_PORTB_DATA_R = 0x0C;
lcdE_Pulse();
for(i=0; i<150; i++)    {
       SysTick_Wait(80);                
    }
GPIO_PORTA_DATA_R = 0x00;
GPIO_PORTB_DATA_R = 0x0C;
lcdE_Pulse();
for(i=0; i<150; i++)    {
       SysTick_Wait(80);                
    }
lcd_zzy_writecommand(0x28);
lcd_zzy_writecommand(0x08); 
lcd_zzy_writecommand(0x0F); 
lcd_zzy_writecommand(0x01);
lcd_zzy_writecommand(0x06);
}

void SysTick_Wait(unsigned long delay){ //名字要改
  NVIC_ST_RELOAD_R = delay-1;  // number of counts to wait
  NVIC_ST_CURRENT_R = 0;       // any value written to CURRENT clears
  while((NVIC_ST_CTRL_R&0x00010000)==0){ // wait for count flag
  }
}

void delay(unsigned long time){
  unsigned long i;
  while(time > 0){
    i = 6666665;
    while(i > 0){
      i = i - 1;
    }
    time = time - 1;
  }
}

void lcdE_Pulse(void){
	PA2 = 1;     
	SysTick_Wait(36); 
	PA2 = 0;     
	SysTick_Wait(36);
}

void lcd_zzy_writecommand(unsigned char c){
PA3 = 0;
//lcdDB = c;
	
SysTick_Wait(3200);
	
//HIGH NIBBLE
GPIO_PORTB_DATA_R  = (c>>2)&0x3C;  
lcdE_Pulse();
SysTick_Wait(80000);
SysTick_Wait(80000);
SysTick_Wait(80000);
SysTick_Wait(80000);
SysTick_Wait(80000);

	//LOW NIBBLE 
GPIO_PORTB_DATA_R  =  (c<<2)&0x3C;    
lcdE_Pulse();
SysTick_Wait(80000);
SysTick_Wait(80000);
SysTick_Wait(80000);
SysTick_Wait(80000);
SysTick_Wait(80000);
}

void lcd_zzy_data(char c){
PA3 = 1;
for (n=0; n<50; n++) {
  SysTick_Wait(80);
}       //50us delay
GPIO_PORTB_DATA_R = (c>>2)&0x3C;  
lcdE_Pulse();
for (n=0; n<200; n++) {
  SysTick_Wait(80);
}     //200us delay
GPIO_PORTB_DATA_R = (c<<2)&0x3C;
lcdE_Pulse();
for (n=0; n<200; n++) {
  SysTick_Wait(80);
}     //200us delay
}

void lcd_go(unsigned char row, unsigned char column) { 
	
	if (row == 0) {
		lcd_zzy_writecommand(0x80 + column);
	} else {
		lcd_zzy_writecommand(0xC0 + column);
	}
	
}

void lcdWriteRamString(char *string) {
	while(*string) {
		lcdWriteData(*string);
		string++;
	}
}
*/
//-------------------------------function of keyboard---------------------------------------------------------------------------
void keypad_Init(void) {
  PortD_Init();
  PortE_Init();
}

unsigned char read_zzy_pad(void){
	int Keyboard_value;
	int my_counter;
	
	GPIO_PORTE_DATA_R = 0x08;
	for (my_counter=0; my_counter<=3; my_counter++){
		
		if (GPIO_PORTE_DATA_R==0x01){ //Check column 1
			if (GPIO_PORTD_DATA_R==0x01){ //Row 1
				Keyboard_value = 1;
				lcdWriteRamString("1");
			}
			else if (GPIO_PORTD_DATA_R==0x02){ //Row 2
				Keyboard_value = 4;
				lcdWriteRamString("4");
			}
			else if (GPIO_PORTD_DATA_R==0x04){ //Row 3
				Keyboard_value = 7;
				lcdWriteRamString("7");
			}
			else if (GPIO_PORTD_DATA_R==0x08){ //Row 4
				Keyboard_value = 14;					//Column 1 Row 4 = 14
				lcdWriteRamString("*");
			}
		}
		
		if (GPIO_PORTE_DATA_R==0x02){ //Check column 2
			if (GPIO_PORTD_DATA_R==0x01){ //Row 1
				Keyboard_value = 2;
				lcdWriteRamString("2");
			}
			else if (GPIO_PORTD_DATA_R==0x02){ //Row 2
				Keyboard_value = 5;
				lcdWriteRamString("5");
			}
			else if (GPIO_PORTD_DATA_R==0x04){ //Row 3
				Keyboard_value = 8;
				lcdWriteRamString("8");
			}
			else if (GPIO_PORTD_DATA_R==0x08){ //Row 4
				Keyboard_value = 0;					
				lcdWriteRamString("0");
			}
		}
		
		else if (GPIO_PORTE_DATA_R==0x04){ //Check column 3
			if (GPIO_PORTD_DATA_R==0x01){ //Row 1
				Keyboard_value = 3;
				lcdWriteRamString("3");
			}
			else if (GPIO_PORTD_DATA_R==0x02){ //Row 2
				Keyboard_value = 6;
				lcdWriteRamString("6");
			}
			else if (GPIO_PORTD_DATA_R==0x04){ //Row 3
				Keyboard_value = 9;
				lcdWriteRamString("9");
			}
			else if (GPIO_PORTD_DATA_R==0x08){ //Row 4
				Keyboard_value = 34;					//Column 3 Row 4 = 34
				lcdWriteRamString("#");
			}
		}
				
		else if (GPIO_PORTE_DATA_R==0x08){ //Check column 3
			if (GPIO_PORTD_DATA_R==0x01){ //Row 1
				Keyboard_value = 41; //Column 4 Row 1 = 41
				lcdWriteRamString("A");
			}
			else if (GPIO_PORTD_DATA_R==0x02){ //Row 2
				Keyboard_value = 42; //Column 4 Row 2 = 42
				lcdWriteRamString("B");
			}
			else if (GPIO_PORTD_DATA_R==0x04){ //Row 3
				Keyboard_value = 43; //Column 4 Row 3 = 43
				lcdWriteRamString("C");
			}
			else if (GPIO_PORTD_DATA_R==0x08){ //Row 4
				Keyboard_value = 44;					//Column 4 Row 4 = 44
				lcdWriteRamString("D");
			}
		}
	
	GPIO_PORTE_DATA_R = GPIO_PORTE_DATA_R<<1;
		if(my_counter==3){
			GPIO_PORTE_DATA_R=0x01;
		}
		SysTick_Wait(40000000);
	}
return Keyboard_value;
}	



//-------------------------------------------------------------function of LCD----------------------------------------------------------------
void SysTick_Wait_ms(unsigned long delay){
    unsigned long i;
    for(i=0; i<delay; i++)    {
       SysTick_Wait(80000);              
    }
}
/**********************************************
***********************************************/
void LCD_w_com(uchar com) //zhi ling xie ru
{
 PA3=0; //RS
 PA4=0; //RW
 GPIO_PORTB_DATA_R =com; //data
 delay_ms(5);
 PA2=1; //EN
 delay_ms(5);
 PA2=0;
}
/**********************************************
***********************************************/
void LCD_w_data(uchar dat) //shu ju xie ru
{
 PA3=1;
 PA4=0;
 GPIO_PORTB_DATA_R=dat;
 delay_ms(5);
 PA2=1;
 delay_ms(5);
 PA2=0;
}
/**********************************************
***********************************************/
void LCD_init()
{
 PA2=0;
 LCD_w_com(0x38);
 LCD_w_com(0x0c);
 LCD_w_com(0x06);
 LCD_w_com(0x01);
}
/**********************************************
***********************************************/
void LCD_disp_cher(uchar x,uchar y,uchar *p)
{
 if(y==1)
 {  
  LCD_w_com(0x80+x);
  while(*p)
  {
  LCD_w_data(*p);
  p++;
  }
 }
 if(y==2)
 {   
  LCD_w_com(0x80+0x40+x);
  while(*p)
  {
  LCD_w_data(*p);
  p++;
  }
 }
}

//--------------------------------------------------------------main-------------------------------------------------------------------
int main (void) {
  SysTick_Init();
	PLL_Init();
  PortA_Init();
  PortB_Init();
  PortD_Init();
  PortE_Init();
  PortF_Init();
  keypad_Init();
  LCD_init();
  while (1) {
    LCD_w_com(0x01);
    read_zzy_pad();
    if (Keyboard_value == 41) {
      LCD_w_com(0x01);
      LCD_disp_cher(1,2,'+');
      read_zzy_pad();
      int a=Keyboard_value;
      read_zzy_pad();
      
    }

  }
}

